home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / fly8111-.000 / fly8111- / fly8 / MSDOS / packet.c < prev    next >
C/C++ Source or Header  |  1979-12-31  |  9KB  |  388 lines

  1. /* --------------------------------- packet.c ------------------------------- */
  2.  
  3. /* This is part of the flight simulator 'fly8'.
  4.  * Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
  5. */
  6.  
  7. /* Handler for packet level exchanges (low level). It uses a packet driver
  8.  * as the communications medium. At the moment it expects etherslip but it
  9.  * is rather general.
  10.  * Here we assume only one handle is used and ANYTYPE was selected. Up to 4
  11.  * drivers can be handled, all call the same fuction with the first argument
  12.  * 'dev' indicating which one it is.
  13.  * Options:
  14.  *  0 interrupt number (usualy 0x65)
  15.  *  1 packet type (default is FLY8_ETYPE which is usualy 0xf8f8)
  16. */
  17.  
  18. #include "fly.h"
  19. #include "pktdrvr.h"
  20.  
  21. #include <dos.h>
  22.  
  23.  
  24. #define MY_OFF(p)    (((Ushort FAR *)&(p))[0])
  25. #define MY_SEG(p)    (((Ushort FAR *)&(p))[1])
  26.  
  27. #define    FLY8_ETYPE    0xf8f8        /* ether packet type */
  28.  
  29. #define MACADDRESS    6
  30.  
  31. #define ETHDEST        0        /* ethernet header */
  32. #define ETHSRCE        (ETHDEST   + MACADDRESS)
  33. #define ETHTYPE        (ETHSRCE   + MACADDRESS)
  34. #define ETHNNN        (ETHTYPE   + 2)
  35.  
  36. #define APADDRESS    MACADDRESS
  37.  
  38. #define APHDEST        0        /* Fly8 header */
  39. #define APHSRCE        (APHDEST   + APADDRESS)
  40. #define APHLEN        (APHSRCE   + APADDRESS)
  41. #define APHNNN        (APHLEN    + 2)
  42.  
  43. #define    PKSSIZE        1024        /* packet-driver's stack size */
  44.  
  45. typedef struct port PORT;
  46. struct port {
  47.     int    flags;
  48. #define POF_ON        0x0001
  49.     void (INTERRUPT FAR *pkint) (void);
  50.     int    iport;
  51.     struct NetDriver *driver;
  52.     short    netport;        /* back-pointer */
  53.     int    intno;            /* packet-driver interrupt */
  54.     Uchar    mac[MACADDRESS];    /* my MAC address */
  55.     Uchar    addr[APADDRESS];    /* my MAC address */
  56.     Uchar    etype[2];        /* eth_type for fly8 */
  57.     int    handle;            /* packet-driver handle */
  58.     PACKET    *pack;            /* packet being received */
  59.     int    *stack;            /* packet-driver stack */
  60.     int    version;
  61.     int    class;
  62.     int    type;
  63.     int    number;
  64.     char    *name;
  65.     int    basic;
  66. };
  67.  
  68. static PORT    ports[] = {
  69.     {0, pkint0, 1},
  70.     {0, pkint1, 2},
  71.     {0, pkint2, 3},
  72.     {0, pkint3, 4}
  73. };
  74. #define    NDEV    (rangeof(ports))
  75.  
  76. static int    nports = 0;        /* number of active ports */
  77.  
  78.  
  79. LOCAL_FUNC void FAR    PktReceivePD (int dev, Ushort di, Ushort si,
  80.     Ushort bp, Ushort dx, Ushort cx, Ushort bx, Ushort ax, Ushort ds,
  81.     Ushort es);
  82. LOCAL_FUNC int NEAR    PktReceiveETH (PORT *port, PACKET *pack);
  83. LOCAL_FUNC int NEAR    PktFindDriver (void);
  84. LOCAL_FUNC int NEAR    PktSendETH (PORT *port, PACKET *p, Uchar *h, int len,
  85.     Uchar *ether_type);
  86. LOCAL_FUNC int NEAR    PktSendAP (PORT *port, PACKET *p, Uchar *h, int len);
  87. LOCAL_FUNC int FAR    PktSend (NETPORT *np, PACKET *p);
  88.  
  89. LOCAL_FUNC void FAR
  90. PktReceivePD (int dev, Ushort di, Ushort si, Ushort bp, Ushort dx, Ushort cx,
  91.     Ushort bx, Ushort ax, Ushort ds, Ushort es)
  92. {
  93.     PORT    *port;
  94.     PACKET    *pack;
  95.     Uchar    *buff;
  96.  
  97.     st.flags1 |= SF_ASYNC;
  98.     switch (ax) {
  99.     case 0:                /* Space allocate call */
  100.         *&es = *&di = 0;
  101.         if (dev < 0 || dev >= NDEV ||
  102.             cx < ETHNNN || cx > (Ushort)PAKPACKLEN)
  103.             goto badret;
  104.         port = &ports[dev];
  105.         if (!(port->flags & POF_ON))
  106.             goto badret;
  107.         if (port->pack) {    /* stray packet? */
  108.             /* stats... */
  109.             packet_del (port->pack);
  110.             port->pack = 0;
  111.         }
  112.         if (F(pack = packet_new (cx, 0)))
  113.             goto badret;
  114.         port->pack = pack;
  115.         buff = pack->data;
  116.         *&es = MY_SEG (buff);
  117.         *&di = MY_OFF (buff);
  118.         break;
  119.     case 1:                /* Packet complete call */
  120.         if (dev < 0 || dev >= NDEV)
  121.             goto badret;
  122.         port = &ports[dev];
  123.         if (!(port->flags & POF_ON))
  124.             goto badret;
  125.         if (F(pack = port->pack))
  126.             goto badret;
  127.         port->pack = 0;
  128.         pack->netport = port->netport;
  129.  
  130.         if (PktReceiveETH (port, pack)) {
  131.             packet_del (pack);
  132.             goto badret;
  133.         }
  134.         break;
  135.     default:
  136. badret:
  137.         ++STATS_NETERRD;
  138.         break;
  139.     }
  140.     st.flags1 &= ~SF_ASYNC;
  141. }
  142.  
  143. /* Accept a Fly8 APplication packet.
  144. */
  145. LOCAL_FUNC int NEAR
  146. PktReceiveAP (PORT *port, PACKET *pack)
  147. {
  148.     int    ret;
  149.     Uchar    *h;
  150.     int    len;
  151.     int    n;
  152.  
  153.     ret = 1;
  154.     do {
  155.         len = pack->length;
  156.         if (len < APHNNN)
  157.             break;
  158.         h = pack->raw;
  159.         n = ComGBw (h+APHLEN);
  160.  
  161. /* Some systems round the size up so we cannot check for exact match.
  162. */
  163.         if (n < 3 || n > len)
  164.             break;
  165.         pack->address = h+APHSRCE;
  166.         pack->raw += APHNNN;
  167.         pack->length = (short)n;
  168.         packet_deliver (pack);
  169.         ret = 0;    /* packet always deleted */
  170.     } while (0);
  171.  
  172.     return (ret);
  173. }
  174.  
  175. /* Accept an incoming ethernet packet. We know it is our special packet type
  176.  * since we requested a selection by the packet driver.
  177. */
  178. LOCAL_FUNC int NEAR
  179. PktReceiveETH (PORT *port, PACKET *pack)
  180. {
  181.     Uchar    *h;
  182.  
  183.     h = pack->raw;
  184.     pack->raw    += ETHNNN;
  185.     pack->length -= ETHNNN;
  186.  
  187.     return (PktReceiveAP (port, pack));
  188. }
  189.  
  190. LOCAL_FUNC int NEAR
  191. PktFindDriver (void)
  192. {
  193.     int    i;
  194.  
  195.     for (i = 0x0060; i < 0x0080; ++i)
  196.         if (test_for_pd (i))
  197.             return (i);
  198.     return (-1);
  199. }
  200.  
  201. LOCAL_FUNC int NEAR
  202. PktOptions (PORT *port, char *options)
  203. {
  204.     long    l;
  205.  
  206.     if (get_narg (options, "int=", &l))
  207.         l = -1;
  208.     port->intno = (int)l;
  209.  
  210.     if (get_narg (options, "type=", &l))
  211.         l = FLY8_ETYPE;
  212.     ComPBw (port->etype, (int)l);
  213.  
  214.     return (0);
  215. }
  216.  
  217. LOCAL_FUNC int FAR
  218. PktInit (NETPORT *np, char *options)
  219. {
  220.     int    portno, rc;
  221.     PORT    *port;
  222.  
  223.     portno = np->unit-'1';
  224.     if (portno < 0 || portno >= NDEV) {
  225.         MsgEPrintf (-100, "%s.%c: bad port",
  226.             np->NetDriver->name, np->unit);
  227.         return (1);
  228.     }
  229.     port = &ports[portno];
  230.     if (port->flags & POF_ON) {
  231.         MsgEPrintf (-100, "%s.%c: already on",
  232.             np->NetDriver->name, np->unit);
  233.         return (1);
  234.     }
  235.  
  236.     port->driver = np->NetDriver;
  237.     port->netport = np->netport;
  238.     if (PktOptions (port, options))
  239.         return (1);
  240.  
  241.     if (-1 == port->intno)
  242.         port->intno = PktFindDriver ();
  243.     else if (!test_for_pd (port->intno))
  244.         port->intno = -1;
  245.     if (-1 == port->intno) {
  246.         MsgEPrintf (-100, "%s.%c: no driver",
  247.             np->NetDriver->name, np->unit);
  248.         return (1);
  249.     }
  250.     MsgPrintf (-100, "Intno 0x%x", port->intno);
  251.  
  252.     if (F(port->stack = (int *)memory_calloc (PKSSIZE,
  253.                         sizeof (*port->stack)))) {
  254.         MsgEPrintf (-100, "%s.%c: no mem",
  255.             np->NetDriver->name, np->unit);
  256.         return (1);
  257.     }
  258.  
  259.     pkinit (portno, PktReceivePD, &port->stack[PKSSIZE]);
  260.  
  261.     port->handle = access_type (port->intno, CL_ETHERNET, ANYTYPE, 0,
  262.         (char FAR *)port->etype, 2, port->pkint);
  263.     if (-1 == port->handle) {
  264.         MsgEPrintf (-100, "%s.%c: no handle",
  265.             np->NetDriver->name, np->unit);
  266.         port->stack = memory_cfree (port->stack, PKSSIZE,
  267.                         sizeof (*port->stack));
  268.         return (1);
  269.     }
  270.     if (driver_info (port->intno, port->handle, &port->version,
  271.             &port->class, &port->type, &port->number, &port->name,
  272.             &port->basic)) {
  273.         port->basic = 1;    /* what else ? */
  274.     }
  275.     MsgPrintf (-100, "Basic 0x%x", port->basic);
  276.  
  277.     port->pack = 0;
  278.     port->flags |= POF_ON;
  279.     ++nports;
  280.  
  281.     rc = get_address (port->intno, port->handle, (char *)port->mac,
  282.                         sizeof (port->mac));
  283.     if (rc) {
  284.         MsgPrintf (-100, "my MAC  failed %0x", Derr);
  285.         memset (port->mac, 0, sizeof (port->mac));
  286.     } else {
  287.         MsgWPrintf (-100, "my  MAC  %02x%02x%02x%02x%02x%02x",
  288.             port->mac[0], port->mac[1], port->mac[2],
  289.             port->mac[3], port->mac[4], port->mac[5]);
  290.     }
  291.     memcpy (port->addr, port->mac, MACADDRESS);
  292.  
  293.     return (0);
  294. }
  295.  
  296. LOCAL_FUNC void FAR
  297. PktTerm (NETPORT *np)
  298. {
  299.     int    portno;
  300.     PORT    *port;
  301.  
  302.     portno = np->unit-'1';
  303.     if (portno < 0 || portno >= NDEV)
  304.         return;
  305.     port = &ports[portno];
  306.     if (!(port->flags & POF_ON))
  307.         return;
  308.     release_type (port->intno, port->handle);
  309.     if (port->pack) {
  310.         packet_del (port->pack);
  311.         port->pack = 0;
  312.     }
  313.     port->flags = 0;
  314.     port->stack = memory_cfree (port->stack, PKSSIZE,
  315.                         sizeof (*port->stack));
  316. }
  317.  
  318. /* Package an ethernet packet.
  319. */
  320. LOCAL_FUNC int NEAR
  321. PktSendETH (PORT *port, PACKET *p, Uchar *h, int len, Uchar *ether_type)
  322. {
  323.     Uchar    *aph;
  324.  
  325.     aph = h;
  326.     len += ETHNNN;
  327.     h   -= ETHNNN;
  328.     memcpy (h+ETHDEST, aph+APHDEST, MACADDRESS);
  329.     memcpy (h+ETHSRCE, port->mac,   MACADDRESS);
  330.     memcpy (h+ETHTYPE, ether_type,  2);
  331.  
  332.     return (send_pkt (port->intno, (char *)h, len));
  333. }
  334.  
  335. /* Package a Fly8 application packet.
  336. */
  337. LOCAL_FUNC int NEAR
  338. PktSendAP (PORT *port, PACKET *p, Uchar *h, int len)
  339. {
  340.     h -= APHNNN;
  341.     if (p->address)
  342.         memcpy (h+APHDEST, p->address, APADDRESS);
  343.     else
  344.         memset (h+APHDEST, 0xff,       APADDRESS);
  345.     memcpy (h+APHSRCE, port->addr, APADDRESS);
  346.     ComPBw (h+APHLEN,  (Uint)len);
  347.     len += APHNNN;
  348.  
  349.     return (PktSendETH (port, p, h, len, port->etype));
  350. }
  351.  
  352. /* Send a packet. Directly called from the main program.
  353. */
  354. LOCAL_FUNC int FAR
  355. PktSend (NETPORT *np, PACKET *p)
  356. {
  357.     PORT    *port;
  358.     int    portno;
  359.     int    ret;
  360.  
  361.     ret = 1;
  362.     do {
  363.         if (!p) {
  364.             ret = 0;
  365.             break;
  366.         }
  367.         portno = np->unit-'1';
  368.         if (portno < 0 || portno >= NDEV)
  369.             break;
  370.         port = &ports[portno];
  371.         if (!(port->flags & POF_ON))
  372.             break;
  373.         ret = PktSendAP (port, p, p->raw, p->length);
  374.     } while (0);
  375.  
  376.     return (ret);
  377. }
  378.  
  379. struct NetDriver NEAR NetPack = {
  380.     "PKT",
  381.     0,
  382.     NULL,    /* extra */
  383.     PktInit,
  384.     PktTerm,
  385.     PktSend,
  386.     0    /* poll */
  387. };
  388.